import { setObj } from '@/common'
import storeFactory from './factory'
export default {
  storeFactory,
  // 抽取store方法
  stateGetter(store) {
    var list = {}
    for (let i in store.state) {
      list[i] = function () {
        if (!this.moduleState) return null
        return this.moduleState[i]
      }
    }
    return list
  },
  actionGetter(store) {
    var list = {}
    for (let i in store.actions) {
      list[i] = function (data) {
        return this.$store.dispatch(this.storeNameCode(i), data)
      }
    }
    return list
  },
  getterGetter(store) {
    var list = {}
    for (let i in store.getters) {
      list[i] = function () {
        return this.$store.getters[this.storeNameCode(i)]
      }
    }
    return list
  },
  mutationGetter(store) {
    var list = {}
    for (let i in store.mutations) {
      list[i] = function (data) {
        var code = this.storeNameCode(i)
        if (this.$store._mutations[code]) {
          return this.$store.commit(code, data)
        } else {
          return null
        }
      }
    }
    return list
  },
  // 获取上级模块的结尾store 用于添加新模块
  getParentStore(target) {
    var parentStore = null
    var parentNode = target
    while (parentNode.$parent) {
      if (parentNode.moduleState) {
        parentStore = parentNode
        break
      } else {
        parentNode = parentNode.$parent
      }
    }
    return parentStore
  },
  // 获取当前的上级模块元素 获取目标的依附模块元素，用于子模块的设置
  getParentElement(target) {
    var parentStore = null
    var parentNode = target
    while (parentNode.$parent) {
      if (parentNode.$options.moduleStore && parentNode !== target) {
        parentStore = parentNode
        break
      } else {
        parentNode = parentNode.$parent
      }
    }
    return parentStore
  },
  bindStoreOption(target, store) {
    // 因为组件共享option选项，因此组件选项绑定只需要在该组件首次加载时进行
    if (target.$options.$storeBind) return
    var options = target.$options
    options.computed = options.computed || {}
    // 将state与getter作为计算方法绑定到组件选项中
    setObj(options.computed, this.stateGetter(store))
    setObj(options.computed, this.getterGetter(store))
    // 将action作为组件方法绑定到选项中
    options.methods = options.methods || {}
    setObj(options.methods, this.actionGetter(store))
    setObj(options.methods, this.mutationGetter(store))
    target.$options.$storeBind = true
  }
}
